#include "QueryProcessor.h"
#include<cstring>
#include<algorithm>
#include<stack>
#include "SPA Front End/SPA_Lexical.h"
#include<boost/algorithm/string.hpp>

using namespace std;


QueryProcessor::QueryProcessor(){
	stat = StatTable::getInstance();
	var = VarTable::getInstance();
	proc = ProcTable::getInstance();
	modstat = ModifyStatTable::getInstance();
	usestat = UsesStatTable::getInstance();
	modvar = ModifyVarTable::getInstance();
	usevar = UsesVarTable::getInstance();
	modproc = ModifyProcTable::getInstance();
	useproc = UsesProcTable::getInstance();
	call = CallsTable::getInstance();
	auxAffects = AuxAffects::getInstance();
	auxAffects->initialize(stat->getNoofEachStmt(STATEMENT_Assign));
}

int QueryProcessor::join(vector<vector<int>>&result, vector<int>&s)
{
	int ssize = s.size(), ressize;
	vector<int> temp;

	if(result.empty())
		result.push_back(s);

	else{
		ressize = result.at(0).size();

		for(int i=0;i<ssize-1;i++)
			for(unsigned int k=0;k<result.size();k++)
				for(int j=0;j<ressize;j++)
					result[k].push_back(result.at(k).at(j));

		for(int i=0;i<ssize;i++){
			if(i==0){
				for(int k=0;k<ressize;k++)
					temp.push_back(s.at(i));
				result.push_back(temp);
			}
			else{
				for(int j=0;j<ressize;j++)
					result.at(result.size()-1).push_back(s.at(i));
			}
		}
	}
	return 1;
}


//--Function to handle Select entity query---
int QueryProcessor::getAll(list<string>&result, vector<QRYSTATEMENT_TYPE> type, vector<WITHATTRIBUTE_TYPE> attribute){
	int x;
	vector<vector<int>>tempres;
	vector<int> s;
	for(unsigned int i=0;i<type.size();i++){
		if(type[i]==_VARIABLE){
			x = var->getTotalSize();
			for(int i=0;i<x;i++){
				NUMERIC_EXPR_TYPE tempo;
				var->getVarType(i,tempo);
				if(tempo == NUMERIC_EXPR_TYPE_VARIABLE)
					s.push_back(i);
			}
		}
		else if(type[i]==_PROCEDURE){
			x = proc->getSize();
			for(int i=0;i<x;i++)
				s.push_back(i);
		}
		else if(type[i]==_CONSTANT){
			x = var->getTotalSize();
			for(int i=0;i<x;i++){
				NUMERIC_EXPR_TYPE tempo;
				var->getVarType(i,tempo);
				if(tempo==NUMERIC_EXPR_TYPE_CONSTANT)
					s.push_back(i);
			}
		}
		else if(type[i]==_CALL && attribute[i]==_PROCNAME){
			x = stat->getNoofStat();
			for(int i=1;i<=x;i++){
				if(stat->getType(i)==_CALL)
					s.push_back(stat->getConditionVar(i));
			}
		}
		else{
			x =  stat->getNoofStat();
			for(int j=1;j<=x;j++){
				if((stat->getType(j) == type[i])||type[i]==_STMT){
					//sprintf(str,"%d",j);
					s.push_back(j);
				}
			}
		}
		join(tempres,s);
		s.clear();
	}

	for(unsigned int j=0;j<tempres[0].size();j++){
		string s = ""; 
		for(unsigned int i=0;i<tempres.size();i++){
			if(type[i] == _VARIABLE || type[i] == _CONSTANT)
				s = s + var->getVarName(tempres[i][j]);
			else if(type[i] == _PROCEDURE)
				s = s + proc->getProcName(tempres[i][j]);
			else if(type[i]==_CALL && attribute[i]==_PROCNAME){
				s = s + proc->getProcName(tempres[i][j]);
			
			}
			else{
				char str[50];
				sprintf_s(str, "%d", tempres[i][j]);
				s = s + str;
			}
			if(i!=tempres.size()-1)
				s = s + " ";
		}
		result.push_back(s);
	}
	return 1;
}

int QueryProcessor::getAll(vector<int>& s, int type){
	//char str[50];
	int x;

	if(type==_VARIABLE){
		x = var->getTotalSize();
		for(int i=0;i<x;i++){
			NUMERIC_EXPR_TYPE tempo;
			var->getVarType(i,tempo);
			if(tempo == NUMERIC_EXPR_TYPE_VARIABLE)
				s.push_back(i);
		}
	}
	else if(type==_PROCEDURE){
		x = proc->getSize();
		for(int i=0;i<x;i++)
			s.push_back(i);
	}
	else if(type==_CONSTANT){
		x = var->getTotalSize();
		for(int i=0;i<x;i++) {
			NUMERIC_EXPR_TYPE tempo;
			var->getVarType(i,tempo);
			if(tempo==NUMERIC_EXPR_TYPE_CONSTANT)
				s.push_back(i);
		}
	}
	else{
		x =  stat->getNoofStat();
		for(int i=1;i<=x;i++){
			if((stat->getType(i) == type)||type==_STMT){
				//sprintf(str,"%d",i);
				s.push_back(i);
			}
		}
	}
	if(s.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getPattern(vector<int>& result, vector<int>& varresult, Argument arg1, Argument arg2, PAT_Argument patarg1){
	if(arg1.argument==_IF || arg1.argument==_WHILE){
		if(arg2.argumentType==ARGUMENT){
			for(int i=1;i<=stat->getNoofStat();i++){
				if(stat->getType(i) == arg1.argument){
					result.push_back(i);
					if(arg2.argument!=_UNDERSCORE){
						varresult.push_back(stat->getConditionVar(i));
					}
				}
			}
		}
		else{
			for(int i=1;i<=stat->getNoofStat();i++){
				if(stat->getType(i)==arg1.argument)
				if(matchExprPattern(i,arg2.argument))
					result.push_back(i);
			}
		}
	}
	else if(arg1.argument==_ASSIGN){
		if(arg2.argumentType==ARGUMENT){
			if(patarg1.argumentType==ARGUMENT){
				for(int i=1;i<=stat->getNoofStat();i++){
					if(stat->getType(i)==arg1.argument){
						result.push_back(i);
						if(arg2.argument!=_UNDERSCORE){
							varresult.push_back((modstat->getVarModified(i))->at(0));
						}
					}
				}
			}
			else{
				for(int i=1;i<=stat->getNoofStat();i++){
					if(matchExprPattern(i,patarg1.stringArgument,PatternPos(patarg1.position))){
						result.push_back(i);
						if(arg2.argument!=_UNDERSCORE){
							varresult.push_back((modstat->getVarModified(i))->at(0));
						}
					}
				}
			}
		}
		else if(arg2.argumentType == VARARGUMENT){
			vector<int> temp = *(modvar->getStmtModifiedIn(arg2.argument));
			if(patarg1.argumentType==ARGUMENT){
				for(unsigned int i=0;i<temp.size();i++){
					if(arg1.argument==stat->getType(temp[i]))
						result.push_back(temp[i]);
				}
			}
			else{
				for(int i=0;i<temp.size();i++)
					if(matchExprPattern(temp[i],patarg1.stringArgument,PatternPos(patarg1.position)))
						result.push_back(temp[i]);
			}
		}
	}
	// <--debugg
	//cout << endl << "::pattern from getPattern::";
	//for ( unsigned int i=0; i<result.size(); i++) {
	//	std::cout << result.at(i) << " ";
	//}
	// -->
	if(result.size()==0)
		return -1;
	return 1;
}

BOOLEAN QueryProcessor::matchExprPattern( STATEMENT_INDEX conditional_stmt_id, VAR_INDEX var_keyIndex ) {
	//--REMOVE THE FOLLOWING LINE AFTER ADDING THIS FUNCTION TO "QueryProcessor.cpp"--
	//StatTable *st = StatTable::getInstance();
	//UsesStatTable *ust = UsesStatTable::getInstance();
	//VarTable *vt = VarTable::getInstance();
	if( stat->getType( conditional_stmt_id ) == STATEMENT_If || stat->getType( conditional_stmt_id ) == STATEMENT_While ) {
		//VAR_INDEX var_keyIndex = vt->getVarIndex ( var_name_key );
		if ( var_keyIndex == -1 ) { //cout << "search var not found\n"; 
			return false; }
		//cout << "first used: " << ust->getVarUsed(conditional_stmt_id).at(0) <<"  search key id:" << var_keyIndex << endl;
		VAR_INDEX temp = stat->getConditionVar(conditional_stmt_id);
		if( temp == var_keyIndex ) {
			return true;
		} else
			return false;
	} else
		return false;
}

BOOLEAN QueryProcessor::matchExprPattern( STATEMENT_INDEX assignment_stmt_id, STRING expr_key, PatternPos pos ) {
	// if expr_key is a valid subexpression in expr_source return true

	//--REMOVE THE FOLLOWING LINE AFTER ADDING THIS FUNCTION TO "QueryProcessor.cpp"--
	//StatTable *st = StatTable::getInstance();

	STRING expr_source;
	if( stat->getType(assignment_stmt_id) == STATEMENT_Assign )
		expr_source = stat->getPattern(assignment_stmt_id); 
	else 
		return false;

	PatternPos foundPos;
	SPA_Lexical lex = SPA_Lexical();
	if (lex.match(expr_key, lex.G_Expression2)) 
	{
		lex.analyze(lex.CONSTRUCT_Expression);
		expr_key = lex.getAssignExpr();
	} else return false;

	INTEGER position;
	INTEGER position_last;
	position = expr_source.find(expr_key);
	position_last = expr_source.rfind(expr_key);
	
	if (  position != string::npos ) {
		//cout << "==MATCH FOUND==";
		if( expr_source.size() == expr_key.size() ) {
			foundPos = PATTERN_entire;
			return true;
		}
		if ( pos == PATTERN_mid )
			return true;
		else if( pos == PATTERN_begin ) {
			// find pattern at begining
				for (int i=0; i < position; i++ ) {
					if (expr_source.at(i) != '[' && 
						expr_source.at(i) != ']' &&
						expr_source.at(i) != '+' && 
						expr_source.at(i) != '-' &&
						expr_source.at(i) != '*' ) {
							// not at begining anymore
							return false;
					}
				}  return true;
			}
			// find pattern at end
			else if( pos == PATTERN_end ) {
				for ( unsigned int i=position_last + expr_key.size(); i < expr_source.size(); i++ ) {
					if (expr_source.at(i) != ']' &&
						expr_source.at(i) != '[' &&
						expr_source.at(i) != '+' &&
						expr_source.at(i) != '-' &&
						expr_source.at(i) != '*' ) {
							// not at end anymore
							return false;
					}
				}  return true;
			} else {
				return false;
			}
			// not at begining and not at end so at middle;
			//else if( pos == PATTERN_mid ){
			//	for ( int i=0; i < position; i++ ) {
			//		if (expr_source.at(i) != '[' && 
			//			expr_source.at(i) != ']' &&
			//			expr_source.at(i) != '+' && 
			//			expr_source.at(i) != '*' ) {
			//				// not at begining anymore
			//				// find pattern at end
			//				for ( unsigned int i=position + expr_key.size(); i < expr_source.size(); i++ ) {
			//					if (expr_source.at(i) != ']' &&
			//						expr_source.at(i) != '[' &&
			//						expr_source.at(i) != '+' && 
			//						expr_source.at(i) != '*' ) {
			//							// not at end anymore
			//							return true;
			//					}
			//				} return false;
			//		}
			//	} return false;
			//}

	} else {
		return false;
	}
}


//------------------Main Function to process Follows query------------------------
int QueryProcessor::getFollow(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	int returnValue;
	if(arg1.argumentType==INTARGUMENT){
		returnValue = getFollowing(result1, result2, arg1.argument, arg2.argument,arg1.argumentType,arg2.argumentType);
		if(returnValue==-1){
			result2.clear();
			result1.clear();
		}
		return returnValue;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getFollowedby(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		if((arg1.argument==arg2.argument)&&(arg1.argumentInd == arg2.argumentInd)&&arg1.argument!=_UNDERSCORE)
			return -1;
		getFollowing(result1, result2, arg1.argument, arg2.argument,arg1.argumentType,arg2.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	/*if(arg2.argumentType!=INTARGUMENT){
	if(result.selectedType == arg2.argument){
	getFollowing(result.resultVector[arg2.argument].resultEntity[arg2.argumentInd], arg1.argument, arg2.argument,arg1.argumentType);
	}
	else if(result.selectedType == arg1.argument)
	getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	else
	getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);*/
	return 1;
}

//------------------Main Function to process Follows* query------------------------
int QueryProcessor::getFollowT(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		int returnValue = getFollowingT(result1, result2, arg1.argument, arg2.argument,arg1.argumentType,arg2.argumentType);
				if(returnValue==-1){
			result2.clear();
			result1.clear();
		}
		return returnValue;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getFollowedbyT(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		if((arg1.argument==arg2.argument)&&(arg1.argumentInd == arg2.argumentInd)&&arg1.argument!=_UNDERSCORE)
			return -1;
		getFollowingT(result1, result2, arg1.argument, arg2.argument,arg1.argumentType,arg2.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	return 1;
}

//------------------Main Function to process Parent query------------------------
int QueryProcessor::getParent(vector<int>& result1,vector<int>& result2, Argument arg1, Argument arg2){
	if(arg2.argumentType==INTARGUMENT){
		int returnValue = getPar(result1,result2, arg1.argument, arg2.argument,arg1.argumentType, arg2.argumentType);
				if(returnValue==-1){
			result2.clear();
			result1.clear();
		}
		return returnValue;
	}
	else if(arg1.argumentType==INTARGUMENT){
		getChild(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else{
		if((arg1.argument==arg2.argument)&&(arg1.argumentInd == arg2.argumentInd)&&arg1.argument!=_UNDERSCORE)
			return -1;
		//getPar(result1, result2,arg1.argument, arg2.argument,arg2.argumentType);
		getChild(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
	}
	/*if(arg1.argumentType!=INTARGUMENT){
	if(result.selectedType == arg1.argument){
	getPar(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd], arg1.argument, arg2.argument,arg2.argumentType);
	}
	else if(result.selectedType == arg2.argument)
	getChild(result.resultVector[arg2.argument].resultEntity[arg2.argumentInd],arg1.argument,arg2.argument,arg1.argumentType);
	}
	else
	getChild(result.resultVector[arg2.argument].resultEntity[arg2.argumentInd],arg2.argument,arg2.argument,arg1.argumentType);*/

	return 1;
}

//------------------Main Function to process Parent* query------------------------
int QueryProcessor::getParentT(vector<int>& result1,vector<int>& result2, Argument arg1, Argument arg2){
	if(arg2.argumentType==INTARGUMENT){
		int returnValue = getParT(result1,result2, arg1.argument, arg2.argument,arg1.argumentType, arg2.argumentType);
				if(returnValue==-1){
			result2.clear();
			result1.clear();
		}
		return returnValue;
	}
	else if(arg1.argumentType==INTARGUMENT){
		getChildT(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result2.size()==0)
			return -1;
	}
	else{
		if((arg1.argument==arg2.argument)&&(arg1.argumentInd == arg2.argumentInd)&&arg1.argument!=_UNDERSCORE)
			return -1;
		//getParT(result1, result2,arg1.argument, arg2.argument,arg2.argumentType);
		getChildT(result1,result2,arg1.argument,arg2.argument,arg1.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
	}
	return 1;
}

int QueryProcessor::getNext(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		int returnValue = getNextafter(result1, result2, arg1.argument, arg2.argument,arg1.argumentType,arg2.argumentType);
				if(returnValue==-1){
			result2.clear();
			result1.clear();
		}
		return returnValue;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getNextbefore(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		if((arg1.argument==arg2.argument)&&(arg1.argumentInd == arg2.argumentInd)&&arg1.argument!=_UNDERSCORE)
			return -1;
		getNextafter(result1, result2, arg1.argument, arg2.argument,arg1.argumentType,arg2.argumentType);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	return 1;
}

int QueryProcessor::getNextT(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		int returnValue = getNextafterT(result1, result2, arg1, arg2);
				if(returnValue==-1){
			result2.clear();
			result1.clear();
		}
		return returnValue;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getNextbeforeT(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		getNextafterT(result1, result2, arg1, arg2);
		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	return 1;
}

int QueryProcessor::getAffects(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		int returnValue = getAffecting(result1, result2, arg1, arg2);
				if(returnValue==-1){
			result2.clear();
			result1.clear();
		}
		return returnValue;
	}
	else if(arg2.argumentType==INTARGUMENT){
		getAffectedby(result1, result2,arg1.argument,arg2.argument,arg2.argumentType);
		if(result1.size()==0)
			return -1;
	}
	else{
		getAffecting(result1, result2, arg1, arg2);
		if(arg1.argument==_UNDERSCORE&&arg2.argument!=_UNDERSCORE){
			std::sort(result2.begin(), result2.end());
			result2.erase(std::unique(result2.begin(), result2.end()), result2.end());
		}

		if(result1.size()==0||result2.size()==0)
			return -1;
		//getFollowedby(result.resultVector[arg1.argument].resultEntity[arg1.argumentInd],arg1.argument,arg2.argument,arg2.argumentType);
	}
	return 1;
}

int QueryProcessor::getAffectsT(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argumentType==INTARGUMENT){
		int returnValue;
		returnValue = AffectsStarLong(arg1.argument,result2,result1,arg1.argument,arg2.argument,arg2.argumentType,false);
		if(returnValue>0)
			return 1;
		else
			return -1;
	}
	else if(arg2.argumentType==INTARGUMENT){
		AffectsStarTLong(arg2.argument,result1);
		if(result1.size()==0)
			return -1;
	}
	else{
		int x = 0;
		for(int i=1;i<=stat->getNoofStat();i++){
			if(stat->getType(i)==_ASSIGN)
				x = AffectsStarLong(i,result2,result1,arg1.argument,arg2.argument,arg2.argumentType,true);
			if(x==2)//for affects*(_,_) case found
				break;
		}
		if(arg1.argument==_UNDERSCORE&&arg2.argument!=_UNDERSCORE){
			std::sort(result2.begin(), result2.end());
			result2.erase(std::unique(result2.begin(), result2.end()), result2.end());
		}
		if(result1.size()==0||result2.size()==0)
			return -1;
	}
	return 1;
}

//BOOLEAN containsAffects( list<affectsNode> &AffectsTreeVisitedNodes, list<affectsNode>::iterator &it,  STATEMENT_INDEX i ) {
//	if( AffectsTreeVisitedNodes.size() >0 ) {
//		it = AffectsTreeVisitedNodes.begin();
//		it = find_if( it, AffectsTreeVisitedNodes.end(), std::bind2nd(findNode(), i ) );
//		if( it != AffectsTreeVisitedNodes.end() && (*it).stmtID == i && (*it).isVisited==false ) 
//			return true;
//		else return false;
//	} else return false;
//};

BOOLEAN QueryProcessor::searchStmtList( STATEMENT_INDEX s1, vector<STATEMENT_INDEX> &searchVector, list<STATEMENT_INDEX>::iterator &it ) {
	for (unsigned int i=0; i<searchVector.size(); i++)
		if ( searchVector.at(i) == s1 )
			return true;
	return false;
};

int QueryProcessor::AffectsStarLong ( STATEMENT_INDEX s1, vector<STATEMENT_INDEX> &resVector2, vector<STATEMENT_INDEX> &resVector1,int t1,int t2,int type2,bool bothWay ) {
	//list<affectsNode> AffectsTreeVisitedNodes;
	vector<STATEMENT_INDEX> UnVisitedNodes;
	vector<STATEMENT_INDEX> VisitedNodes;
	//list<affectsNode>::iterator it;
	list<STATEMENT_INDEX>::iterator iit;
	vector<STATEMENT_INDEX> v1;
	vector<STATEMENT_INDEX> v2;
	STATEMENT_INDEX currStmt = 0;
	bool boolflag = false;

	// <-- function private data.. donot touch
	vector< STATEMENT_INDEX> resV2;
	// -- >
	//affectsNode a;
	//
	Argument arg1, arg2;
	arg1.argumentType = INTARGUMENT;
	arg1.argument = s1;
	arg2.argumentType = ARGUMENT;
	arg2.argument = _STMT;
	//

	//m.getNextafterT(v1, v2, arg1, arg2);
	getAffecting(v1, v2, arg1, arg2);

	// push all affects of s1.
	for( int i=0; i<v2.size(); i++ ) {
		//currStmt = v2.at(i);
		//a.stmtID = currStmt; a.isVisited = false;
		//UnVisitedNodes.push_back( a.stmtID );
		UnVisitedNodes.push_back( v2.at(i) );
	};
	while ( !UnVisitedNodes.empty() ) { // O(n*n)
		//arg1.argument = AffectsTreeVisitedNodes.back().stmtID;
		arg1.argument = UnVisitedNodes.back();  // next node to be computed "k"

		// <-- donot touch..
		resV2.push_back( UnVisitedNodes.back() );
		// -->
		resVector2.push_back( UnVisitedNodes.back() ); //
		resVector1.push_back(s1);

		// <-- sesha.. optimization..
		if(!bothWay){
			if(type2==INTARGUMENT)
				if(UnVisitedNodes.back() == t2){
					boolflag=true;
					return 1;
				}
		}
		if(t1==_UNDERSCORE&&t2==_UNDERSCORE)
			return 2;
		if(bothWay){
		if(t2==_UNDERSCORE&&t1!=_UNDERSCORE)
			return 1;
		}
		// -->
		currStmt = UnVisitedNodes.back();
		UnVisitedNodes.pop_back();

		v2.clear();
		getAffecting(v1, v2, arg1, arg2); // get all statements that affect

		for( int i=0; i<v2.size(); i++ ) { // store all statements that affect "k"
			//if( currStmt == s2 ) // found s2; therefore Affects*(s1, s2) is true
			//	return true;
			//currStmt = v2.at(i);
			//a.stmtID = currStmt; a.isVisited = false;
			//if( !containsAffects( AffectsTreeVisitedNodes, it, currStmt ) )
				//AffectsTreeVisitedNodes.push_back( a );
			//if ( !searchStmtList(v2.at(i), VisitedNodes, iit ) && !searchStmtList(v2.at(i), UnVisitedNodes, iit ) )
			if ( !searchStmtList(v2.at(i), resV2, iit ) && !searchStmtList(v2.at(i), UnVisitedNodes, iit ) )
				UnVisitedNodes.push_back(v2.at(i));
		};
	}
	if(boolflag==false&&type2==INTARGUMENT)
		return -1;
	if(resVector2.size()==0)
		return -1;
	return 1;
};

BOOLEAN QueryProcessor::AffectsStarTLong ( STATEMENT_INDEX s1, vector<STATEMENT_INDEX> &resVector ) {
	//list<affectsNode> AffectsTreeVisitedNodes;
	vector<STATEMENT_INDEX> UnVisitedNodes;
	vector<STATEMENT_INDEX> VisitedNodes;
	//list<affectsNode>::iterator it;
	list<STATEMENT_INDEX>::iterator iit;
	vector<STATEMENT_INDEX> v1;
	vector<STATEMENT_INDEX> v2;
	STATEMENT_INDEX currStmt = 0;

	//affectsNode a;
	//
	Argument arg1, arg2;
	arg1.argumentType = ARGUMENT;
	arg1.argument = _STMT;
	arg2.argumentType = INTARGUMENT;
	arg2.argument = s1;
	//

	//m.getNextafterT(v1, v2, arg1, arg2);
	getAffectedby(v1, v2, arg1.argument, arg2.argument,arg2.argumentType);

	// push all affects of s1.
	for( int i=0; i<v1.size(); i++ ) {
		//currStmt = v2.at(i);
		//a.stmtID = currStmt; a.isVisited = false;
		//UnVisitedNodes.push_back( a.stmtID );
		UnVisitedNodes.push_back( v1.at(i) );
	};
	while ( !UnVisitedNodes.empty() ) { // O(n*n)
		//arg1.argument = AffectsTreeVisitedNodes.back().stmtID;
		arg2.argument = UnVisitedNodes.back();  // next node to be computed "k"
		//AffectsTreeVisitedNodes.back().isVisited = true;
		//AffectsTreeVisitedNodes.pop_back();

		//VisitedNodes.push_back( UnVisitedNodes.back() ); // 
		resVector.push_back( UnVisitedNodes.back() ); // 
		currStmt = UnVisitedNodes.back();
		UnVisitedNodes.pop_back();

		v1.clear();
		getAffectedby(v1, v2, arg1.argument, arg2.argument,arg2.argumentType); // get all statements that affect

		for( int i=0; i<v1.size(); i++ ) { // store all statements that affect "k"
			//if( currStmt == s2 ) // found s2; therefore Affects*(s1, s2) is true
			//	return true;
			//currStmt = v2.at(i);
			//a.stmtID = currStmt; a.isVisited = false;
			//if( !containsAffects( AffectsTreeVisitedNodes, it, currStmt ) )
				//AffectsTreeVisitedNodes.push_back( a );

			//if ( !searchStmtList(v2.at(i), VisitedNodes, iit ) && !searchStmtList(v2.at(i), UnVisitedNodes, iit ) )
			if ( !searchStmtList(v1.at(i), resVector, iit ) && !searchStmtList(v1.at(i), UnVisitedNodes, iit ) )
				UnVisitedNodes.push_back(v1.at(i));
		};
	}
	return false;
};

//------------------Main Function to process Modifies query------------------------
int QueryProcessor::getModify(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2) 
{
	int resultExists=0;

	/*if(arg1.argumentType==result.selectedType && arg1.argumentInd!=result.resultIndex)
	result.resultType==RESULT_BOOLEAN;

	else if(arg2.argumentType==result.selectedType && arg2.argumentInd!=result.resultIndex)
	result.resultType==RESULT_BOOLEAN;*/

	if(arg1.argumentType==ARGUMENT && arg2.argumentType==VARARGUMENT)
		resultExists=getModifies(result1, result2,arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	else if(arg1.argumentType!=ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getModifiedBy(result1, result2, arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getModifies(result1, result2,arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	else if((arg1.argumentType==INTARGUMENT || arg1.argumentType==PROCARGUMENT) && arg2.argumentType==VARARGUMENT)
		resultExists=getModifies(result1, result2,arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	/*if(result.resultType==RESULT_BOOLEAN)
	{
	if(result.resultVector.size()>0)
	result.resultExists = true;
	else
	result.resultExists = false;
	}*/

	return resultExists;
}
//------------------Main Function to process Uses query------------------------
int QueryProcessor::getUses(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	int resultExists;

	/*if(arg1.argumentType==result.selectedType && arg1.argumentInd!=result.resultIndex)
	result.resultType==RESULT_BOOLEAN;

	else if(arg2.argumentType==result.selectedType && arg2.argumentInd!=result.resultIndex)
	result.resultType==RESULT_BOOLEAN;*/

	if(arg1.argumentType==ARGUMENT && arg2.argumentType==VARARGUMENT)
		resultExists=getUsess(result1, result2,arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	else if(arg1.argumentType!=ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getUsedBy(result1, result2, arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
		resultExists=getUsess(result1, result2,arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	else if((arg1.argumentType==INTARGUMENT || arg1.argumentType==PROCARGUMENT) && arg2.argumentType==VARARGUMENT)
		resultExists=getUsess(result1, result2,arg1.argument,arg1.argumentType,arg2.argument,arg2.argumentType);

	/*if(result.resultType==RESULT_BOOLEAN)
	{
	if(result.resultVector.size()>0)
	result.resultExists = true;
	else
	result.resultExists = false;
	}
	*/
	return resultExists;
}

//------------------Main Function to process Calls query------------------------

int QueryProcessor::getCalls(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	vector<PROC_INDEX> temp;
	/* Select p ... Calls(p,"q")*/
	if(arg1.argumentType==ARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		for(int i=0;i<proc->getSize();i++)
		{
			if(call->isCalled(i,arg2.argument))
				result1.push_back(i);
		}

		return 2;
	}

	/*Select p ... Calls("q",p)*/
	else if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==ARGUMENT)
	{
		result2 = *(call->getProcCalled(arg1.argument));

		if(result2.at(0)==-1)
			result2.pop_back();
		return 2;
	}

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
	{
		/*Select p ... Calls(p,q)*/

		if(arg1.argumentInd==arg2.argumentInd)
			return -2;

		if(arg1.argument==_UNDERSCORE)
		{
			for(int i=0;i<proc->getSize();i++)
				for(int j=0;j<proc->getSize();j++)
					if(call->isCalled(j,i))
					{
						result2.push_back(i);
						break;
					}

			return 2;
		}

		for(int i=0;i<proc->getSize();i++)
		{
			temp = *(call->getProcCalled(i));

			for(unsigned int j=0;j<temp.size();j++)
			{
				if(temp.at(j)!=-1)
				{
					if(arg2.argument==_UNDERSCORE)
					{
						result1.push_back(i);
						break;
					}

					else if(arg1.argument==_UNDERSCORE && arg2.argument==_UNDERSCORE)
					{	for(int i=0;i<proc->getSize();i++)
							for(int j=0;j<proc->getSize();j++)
								if(i!=j)
									if(call->isCalled(i, j))
										return 1;
						return -1;
					}

					else 
					{
						result1.push_back(i);
						result2.push_back(temp.at(j));
					}
				}
			}

			temp.clear();

		}

		return 2;
	}

	if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		if(call->isCalled(arg1.argument, arg2.argument))
			return 1;
		else return -1;
	}

	return -2;
}

//------------------Main Function to process Calls* query------------------------

int QueryProcessor::getCallsT(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2)
{
	vector<PROC_INDEX> temp;

	/*Select p ... Calls*("q",p)*/
	if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==ARGUMENT)
	{
		result2 = *(call->getCallsStar(arg1.argument));
		if(result2.at(0)==-1)
			result2.pop_back();

		return 2;
	}

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		for(int i=0;i<proc->getSize();i++)
		{
			if(call->isCalledStar(i,arg2.argument))
				result1.push_back(i);
		}

		return 2;
	}

	else if(arg1.argumentType==ARGUMENT && arg2.argumentType==ARGUMENT)
	{
		/*Select p ... Calls(p,q)*/
		if(arg1.argumentInd==arg2.argumentInd)
			return -2;

		if(arg1.argument==_UNDERSCORE)
		{
			for(int i=0;i<proc->getSize();i++)
				for(int j=0;j<proc->getSize();j++)
					if(call->isCalled(j,i))
					{
						result2.push_back(i);
						break;
					}

			return 2;
		}

		for(int i=0;i<proc->getSize();i++)
		{
			temp=*(call->getCallsStar(i));

			for(unsigned int j=0;j<temp.size(); j++)
			{
				if(temp.at(j)!=-1)
				{
					if(arg2.argument==_UNDERSCORE)
					{
						result1.push_back(i);
						break;
					}

					else if(arg1.argument==_UNDERSCORE && arg2.argument==_UNDERSCORE)
					{
						for(int j=0;j<proc->getSize();j++)
							if(i!=j)
								if(call->isCalledStar(i, j))
									return 1;
						return -1;
					}

					else 
					{
						result1.push_back(i);
						result2.push_back(temp.at(j));
					}
				}
			}

		}


		return 2;
	}

	if(arg1.argumentType==PROCARGUMENT && arg2.argumentType==PROCARGUMENT)
	{
		if(call->isCalledStar(arg1.argument, arg2.argument))
			return 1;
		else return -1;
	}

	return -2;
}

int QueryProcessor::getFollowing(vector<int>&result1, vector<int>& result2,int t1, int t2, int type1, int type2){
	int blockEnd;
	if(type1==INTARGUMENT){
		blockEnd = stat->getBlockEnd(t1);
		if(blockEnd!=-1){
			if(type2==INTARGUMENT){
				if(blockEnd==t2)
					return 1;
			}
			else if((STATEMENT_TYPE(t2) == stat->getType(blockEnd))||t2==_STMT||t2==_UNDERSCORE){
				result1.push_back(t1);
				result2.push_back(blockEnd);
			}
		}
	}
	else{
		bool isThere;
		for(int i=0;i<stat->getNoofStat()-1;i++){
			if((STATEMENT_TYPE(t1)==stat->getType(i+1))||t1==_STMT||t1==_UNDERSCORE){
				blockEnd = stat->getBlockEnd(i+1);
				if(blockEnd!=-1){
					if((STATEMENT_TYPE(t2) == stat->getType(blockEnd))||t2==_STMT||t2==_UNDERSCORE){
						if(t2==_UNDERSCORE&&t1!=_UNDERSCORE){
							isThere = false;
						for(int j=0;j<result1.size();j++){
							if(result1[j]==i+1){
								isThere = true;
								break;
							}
						}
						if(isThere)
							continue;
						}
						result1.push_back(i+1);
						result2.push_back(blockEnd);
						if(t1==_UNDERSCORE&&t2==_UNDERSCORE)
							break;
					}
				}
			}
		}
	}
	if(result2.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getFollowedby(vector<int>&result1, vector<int>& result2,int t1, int t2,int type2){
	int blockEnd;
	PROC_INDEX p;
	if(type2==INTARGUMENT){
		p = proc->getProcIn(t2);
		for(int j=t2-1;j>=proc->getRangeStart(p);j--){
			blockEnd = stat->getBlockEnd(j);
			if(blockEnd==t2){
				if((STATEMENT_TYPE(t1) == stat->getType(j))||t1==_STMT||t1==_UNDERSCORE){
					result1.push_back(j);  //push back the statement number
					result2.push_back(t2);
					break;
				}
			}
		}
	}
	else{
		for(unsigned int j=stat->getNoofStat()-1;j>=0;j--)
			if((STATEMENT_TYPE(t2) == stat->getType(j+1))||t2==_STMT||t2==_UNDERSCORE){
				p = proc->getProcIn(j+1);
				for(int i=j; i>=proc->getRangeStart(p);i--){
					blockEnd = stat->getBlockEnd(i);
					if(blockEnd==j+1){ //if block end equals the statemnt number
						if((STATEMENT_TYPE(t1)==stat->getType(i))||t1==_STMT||t1==_UNDERSCORE){
							result1.push_back(i); // push back the statement number
							result2.push_back(j+1);
							break;
						}
					}
				}
			}
	}
	return -1;
}

int QueryProcessor::getFollowingT(vector<int>&result1, vector<int>& result2,int t1,int t2, int type1, int type2){
	int stmtnum;
	bool boolflag = false;
	if(type1==INTARGUMENT){
		stmtnum=stat->getBlockEnd(t1);
		//lastst=stmtNo.size();
		while(stmtnum!=-1){
			if(type2==INTARGUMENT){
				if(stmtnum == t2){
					boolflag = true;
					return 1;
				}
				result1.push_back(t1);
				result2.push_back(stmtnum);

			}
			else if((STATEMENT_TYPE(t2) == stat->getType(stmtnum))  ||  t2==_STMT || t2==_UNDERSCORE){
				result1.push_back(t1);
				result2.push_back(stmtnum);
				if(t2==_UNDERSCORE)
					break;
			}
			stmtnum = stat->getBlockEnd(stmtnum);
		}
	}
	else{
		bool isThere;
		int j;
		vector<int> tempVector;
		for(int i=0;i<stat->getNoofStat()-1;i++){
			isThere = false;
			if(t1==_UNDERSCORE&&t2!=_UNDERSCORE){
			for(j=0;j<tempVector.size();j++){
				if(tempVector[j]==i+1){
					isThere = true;
					break;
				}
			}
			}

			if(t1==_UNDERSCORE&&t2!=_UNDERSCORE){
				if(isThere)
					continue;
			}


				if((STATEMENT_TYPE(t1)==stat->getType(i+1))||t1==_STMT||t1==_UNDERSCORE){
					stmtnum = stat->getBlockEnd(i+1);
					//lastst = stmtNo.size();
					while(stmtnum!=-1){
						tempVector.push_back(stmtnum);
						if((STATEMENT_TYPE(t2) == stat->getType(stmtnum))||(t2==_STMT)||(t2==_UNDERSCORE)){
							if(t2==_UNDERSCORE&&t1!=_UNDERSCORE){
								isThere = false;
								for(int j=0;j<result1.size();j++)
									if(result1[j]==i+1){
										isThere = true;
										break;
									}
									if(isThere)
										break;
							}
							result1.push_back(i+1);
							result2.push_back(stmtnum);
							if(t1==_UNDERSCORE&&t2==_UNDERSCORE)
								return 1;
						}
						stmtnum = stat->getBlockEnd(stmtnum);
					}
					if(t2==_UNDERSCORE&&t1!=_UNDERSCORE)
						if(isThere)
							continue;
				}
		}
	}
	if(type2==INTARGUMENT&&boolflag==false)
		return -1;
	if(result2.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getFollowedbyT(vector<int>& result1,vector<int>& result2,int t1, int t2, int type2){
	int stmtnum;	
	PROC_INDEX p = proc->getProcIn(t2);
	if(type2==INTARGUMENT){
		stmtnum = t2;
		for(int j=t2-1;j>=proc->getRangeStart(p);j--){
			if(stat->getBlockEnd(j)==stmtnum){
				stmtnum = j;
				if((STATEMENT_TYPE(t1) == stat->getType(stmtnum))||t1==_STMT||t1==_UNDERSCORE){
					result1.push_back(stmtnum);
					result2.push_back(t2);
					if(t1==_UNDERSCORE)
						break;
				}
			}
		}
	}
	else{
		vector<int> tempVector;
		for(int j=stat->getNoofStat()-1;j>=0;j--){
			/*isThere = false;
			for(k=0;k<tempVector.size();k++){
			if(tempVector[k]==j+1){
			isThere=true;
			break;
			}
			}*/
			//if(!isThere){
			stmtnum = j+1;
			if((STATEMENT_TYPE(t2) == stat->getType(stmtnum))||t2==_STMT||t2==_UNDERSCORE){
				p = proc->getProcIn(stmtnum);
				for(int i=j; i>=proc->getRangeStart(p);i--){
					if(stat->getBlockEnd(i)==stmtnum){
						stmtnum = i;
						tempVector.push_back(stmtnum);// push back statement number
						if((STATEMENT_TYPE(t1)==stat->getType(stmtnum))||t1==_STMT||t1==_UNDERSCORE){
							result1.push_back(stmtnum);
							result2.push_back(j+1);
						}
					}
				}
			}
			//}
		}
	}
	return -1;
}

int QueryProcessor::getNextafter(vector<int>&result1, vector<int>& result2,int t1, int t2, int type1, int type2){
	vector<int> next;
	if(type1==INTARGUMENT){
		next = *(stat->getNext(t1));
		if(next.size()!=0){
			for(unsigned int i=0;i<next.size();i++){
				if(type2 == INTARGUMENT){
					if(next[i]==t2)
						return 1;
				}
				else if((STATEMENT_TYPE(t2) == stat->getType(next[i]))||t2==_STMT||t2==_UNDERSCORE){
					result1.push_back(t1);
					result2.push_back(next[i]);
					if(t2==_UNDERSCORE)
						break;
				}
			}
		}
	}
	else{
		bool isThere;
		for(int i=0;i<stat->getNoofStat()-1;i++){
			isThere = false;
			if((STATEMENT_TYPE(t1)==stat->getType(i+1))||t1==_STMT||t1==_UNDERSCORE){
				next = *(stat->getNext(i+1));
				if(next.size()!=0){
					for(unsigned int j=0;j<next.size();j++){
						if((STATEMENT_TYPE(t2) == stat->getType(next[j]))||t2==_STMT||t2==_UNDERSCORE){
							if(t2==_UNDERSCORE&&t1!=_UNDERSCORE){
								for(int m=0;m<result1.size();m++){
									if(result1[m]==i+1){
										isThere = true;
										break;
									}
								}
								if(isThere)
									break;
							}
							result1.push_back(i+1);
							result2.push_back(next[j]);
							if(t1==_UNDERSCORE&&t2==_UNDERSCORE)
								return 1;
						}
					}
				}
			}
		}
	}
	if(result2.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getNextbefore(vector<int>& result1, vector<int>&result2, int t1, int t2,int type2){
	vector<int> next;
	PROC_INDEX p;
	unsigned m;
	if(type2==INTARGUMENT){
		p = proc->getProcIn(t2);
		for(int j=t2-1;j>=proc->getRangeStart(p);j--){
			next = *(stat->getNext(j));
			for(unsigned int n=0;n<next.size();n++){
				if(next[n]==t2){
					if((STATEMENT_TYPE(t1) == stat->getType(next[n]))||t1==_STMT||t1==_UNDERSCORE){
						for(m=0;m<result1.size();m++)
							if(result1[m]==j)
								break;
						if(m==result1.size()){
							result1.push_back(j);  //push back the statement number
							//result2.push_back(t2);
						}
					}
				}
			}
		}
		if(stat->getType(t2) == _WHILE){
			int blockend = stat->getBlockEnd(t2);
			if(blockend!=-1){
				if(t2==stat->getParent(blockend-1)){
					if((STATEMENT_TYPE(t1) == stat->getType(blockend-1))||t1==_STMT||t1==_UNDERSCORE){
						for(unsigned int m=0;m<result1.size();m++)
							if(result1[m]==blockend-1)
								return -1;
						result1.push_back(blockend-1);
						result2.push_back(t2);
					}
				}
				else{
					int temp = stat->getParent(blockend-1);
					int stmtnum;
					while(1){
						stmtnum = temp;
						temp = stat->getParent(temp);
						if(temp==t2)
							break;
					}
					if((STATEMENT_TYPE(t1) == stat->getType(stmtnum))||t1==_STMT||t1==_UNDERSCORE){
						for(unsigned int m=0;m<result1.size();m++)
							if(result1[m]==stmtnum)
								return -1;
						result1.push_back(stmtnum);
						result2.push_back(t2);
					}
				}
			}
			else{
				int k;
				for(k=t2+1;k<=proc->getRangeEnd(p);k++){
					if(stat->getParent(k)<t2)
						break;
				}
				if(t2==stat->getParent(k-1)){
					if((STATEMENT_TYPE(t1) == stat->getType(k-1))||t1==_STMT||t1==_UNDERSCORE){
						for(unsigned int m=0;m<result1.size();m++)
							if(result1[m]==k-1)
								return -1;
						result1.push_back(k-1);
						result2.push_back(t2);
					}
				}
				else{
					int temp = stat->getParent(k-1);
					int stmtnum;
					while(1){
						stmtnum = temp;
						temp = stat->getParent(temp);
						if(temp==t2)
							break;
					}
					if((STATEMENT_TYPE(t1) == stat->getType(stmtnum))||t1==_STMT||t1==_UNDERSCORE){
						for(unsigned int m=0;m<result1.size();m++)
							if(result1[m]==stmtnum)
								return -1;
						result1.push_back(stmtnum);
						result2.push_back(t2);
					}
				}
			}
		}
	}
	else{
		for(int j=stat->getNoofStat()-1;j>=0;j--)
			if((STATEMENT_TYPE(t2) == stat->getType(j+1))||t2==_STMT||t2==_UNDERSCORE){
				p = proc->getProcIn(j+1);
				for(int i=j; i>=proc->getRangeStart(p);i--){
					next = *(stat->getNext(i));
					for(unsigned int n=0;n<next.size();n++){
						if(next[n]==j+1){ //if next equals the statemnt number
							if((STATEMENT_TYPE(t1)==stat->getType(next[n]))||t1==_STMT||t1==_UNDERSCORE){
								result1.push_back(next[n]); // push back the statement number
								result2.push_back(j+1);
							}
						}
					}
				}
				if(stat->getType(j+1) == _WHILE){
					int stmtnum = j+1;
					int blockend = stat->getBlockEnd(stmtnum);
					if(blockend!=-1){
						if((STATEMENT_TYPE(t1) == stat->getType(blockend-1))||t1==_STMT||t1==_UNDERSCORE){
							result1.push_back(blockend-1);
							result2.push_back(stmtnum);
						}	    
					}
					else{
						int k;
						p = proc->getProcIn(stmtnum);
						for(k=stmtnum+1;k<=proc->getRangeEnd(p);k++){
							if(stat->getParent(k)<t2)
								break;
						}
						if((STATEMENT_TYPE(t1) == stat->getType(k-1))||t1==_STMT||t1==_UNDERSCORE){
							result1.push_back(k-1);
							result2.push_back(t2);
						}
					}
				}
			}
	}
	return -1;
}

int QueryProcessor::getNextafterT(vector<int>&result1, vector<int>& result2,Argument arg1, Argument arg2){
	bool boolflag = false;
	if(arg1.argumentType==INTARGUMENT){
		vector<int> next = *(stat->getNext(arg1.argument));
		vector<int> temp;
		bool isfound;
		if(next.size()!=0){
			for(unsigned int n=0;n<next.size();n++){
				temp.push_back(next[n]);
			}
			for(unsigned int i=0;i<temp.size();i++){
				if(arg2.argumentType==INTARGUMENT){
					if(temp[i] == arg2.argument){
						boolflag = true;
						return 1;
					}
					result2.push_back(temp[i]);
				}
				else if((STATEMENT_TYPE(arg2.argument) == stat->getType(temp[i]))||(arg2.argument==_STMT)||(arg2.argument==_UNDERSCORE)){
					result2.push_back(temp[i]);
					if(arg2.argument==_UNDERSCORE)
						break;
				}
				next = *(stat->getNext(temp[i]));
				for(unsigned int n=0;n<next.size();n++){
					isfound=false;
					for(unsigned int k=0;k<temp.size();k++){
						if(temp[k]==next[n]){
							isfound=true;
							break;
						}
					}
					if(!isfound)
						temp.push_back(next[n]);
				}
			}
		}

		/*for(unsigned int i=t1;i<end;i++){
		for(int k=0;k<temp.size();k++){
		if(temp[k]==i){
		isfound = true;
		break;
		}
		}
		if(isfound){
		next = stat->getNext(i);
		for(unsigned int i=0;i<next.size();i++){
		temp.push_back(next[i]);
		if((STATEMENT_TYPE(t2) == stat->getType(next[i]))||(t2==_STMT)){
		result2.push_back(next[i]);				
		}
		}
		}
		isfound = false;
		}*/
	}	
	else{
		vector<int>next;
		vector<int> temp;
		vector<int> duplicateelim;
		bool isfound;
		bool isNextofself;
		bool isThere;
		for(int i=0;i<stat->getNoofStat();i++){
			isThere = false;
			if(arg1.argument==_UNDERSCORE&&arg2.argument!=_UNDERSCORE){
				for(int j=0;j<duplicateelim.size();j++){
					if(duplicateelim[j]==i+1){
						isThere=true;
						break;
					}
				}
				if(isThere)
					continue;
			}
			temp.clear();
			next.clear();
			if((STATEMENT_TYPE(arg1.argument)==stat->getType(i+1))||arg1.argument==_STMT||arg1.argument==_UNDERSCORE){
				int stmtnum = i+1;
				isNextofself=false;
				next = *(stat->getNext(stmtnum));
				if(next.size()!=0){
					for(unsigned int n=0;n<next.size();n++){
						temp.push_back(next[n]);
						if(arg1.argument==_UNDERSCORE&&arg2.argument!=_UNDERSCORE)
						duplicateelim.push_back(next[n]);
					}
					for(unsigned int j=0;j<temp.size();j++){
						if((STATEMENT_TYPE(arg2.argument) == stat->getType(temp[j]))||(arg2.argument==_STMT)||(arg2.argument==_UNDERSCORE)){
							if((arg1.argument==arg2.argument)&&(arg1.argumentInd==arg2.argumentInd)&&arg1.argument!=_UNDERSCORE){
								if(temp[j]==stmtnum){
									result1.push_back(stmtnum);
									result2.push_back(temp[j]);
									isNextofself = true;
									break;
								}
							}
							else{
								result1.push_back(stmtnum);
								result2.push_back(temp[j]);
								if(arg1.argument!=_UNDERSCORE&&arg2.argument==_UNDERSCORE){
									break;
								}
								if(arg1.argument==_UNDERSCORE&&arg2.argument==_UNDERSCORE)
									return 1;
							}
						}
						if(isNextofself)
							continue;
						next = *(stat->getNext(temp[j]));
						for(unsigned int n=0;n<next.size();n++){
							isfound=false;
							for(unsigned int k=0;k<temp.size();k++){
								if(temp[k]==next[n]){
									isfound=true;
									break;
								}
							}
							if(!isfound){
								temp.push_back(next[n]);
								if(arg1.argument==_UNDERSCORE&&arg2.argument!=_UNDERSCORE)
									duplicateelim.push_back(next[n]);
							}
						}
					}
				}
			}
		}
	}
	if(arg2.argumentType==INTARGUMENT&&boolflag==false)
		return -1;
	if(result2.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getNextbeforeT(vector<int>& result1, vector<int>&result2, int t1, int t2,int type2){
	vector<int> next;
	vector<int> temp1;
	if(type2==INTARGUMENT){
		int x = getNextbefore(temp1,result2,t1,t2,type2);
		for(unsigned int i=0;i<temp1.size();i++){
			if((STATEMENT_TYPE(t1) == stat->getType(temp1[i]))||t1==_STMT||t1==_UNDERSCORE){
				result1.push_back(temp1[i]);
				if(t1==_UNDERSCORE)
					break;
			}
			getNextbefore(temp1,result2,t1,temp1[i],INTARGUMENT);

		}
	}
	return -1;
}

int QueryProcessor::getPar(vector<int>& result1,vector<int>& result2,int t1, int t2, int type1, int type2){
	int parent;
	if(type2==INTARGUMENT){
		parent = stat->getParent(t2);
		if(parent!=-1){
			if(type1==INTARGUMENT){
				if(t1 == parent)
					return 1;
			}
			else if((STATEMENT_TYPE(t1) == stat->getType(parent))||t1==_STMT||t1==_UNDERSCORE){
				result1.push_back(parent);
				result2.push_back(t2);
			}
		}
	}
	else{
		for(unsigned int i=stat->getNoofStat()-1;i>=0;i--){
			if((STATEMENT_TYPE(t2)==stat->getType(i+1))||t2==_STMT||t2==_UNDERSCORE){
				parent = stat->getParent(i+1);
				if(parent!=-1)
					if((STATEMENT_TYPE(t1) == stat->getType(parent))||t1==_STMT||t1==_UNDERSCORE){
						result1.push_back(parent);
						result2.push_back(i+1);
					}
			}
		}
	}
	if(result1.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getChild(vector<int>& result1,vector<int>& result2,int t1, int t2,int type1){
	PROC_INDEX p;
	int blockEnd;
	int rangeEnd;
	if(type1==INTARGUMENT){
		p = proc->getProcIn(t1);
		rangeEnd = proc->getRangeEnd(p);
		int l;
		for(int j=t1+1;j<=rangeEnd;){
			if(stat->getParent(j)<t1)
				break;
			else if(stat->getParent(j)==t1){
				if((STATEMENT_TYPE(t2) == stat->getType(j))||t2==_STMT||t2==_UNDERSCORE){
					result1.push_back(t1);
					result2.push_back(j);//push back statement
				}
			}
			blockEnd = stat->getBlockEnd(j);
			if(blockEnd!=-1)
				j = blockEnd;
			else{
				for(l=j+1;l<=rangeEnd;l++){
					if(stat->getParent(l)<j){
						break;
					}
				}
				j = l;
			}
		}
	}
	else{
		int l;
		for(int j=0;j<stat->getNoofStat();j++)
			if((STATEMENT_TYPE(t1) == stat->getType(j+1))||t1==_STMT||t1==_UNDERSCORE){
				p = proc->getProcIn(j+1);
				rangeEnd = proc->getRangeEnd(p);
				for(int i=j+2; i<=rangeEnd;){
					if(stat->getParent(i)<j+1)
						break;
					if(stat->getParent(i)==j+1){
						if((STATEMENT_TYPE(t2)==stat->getType(i))||t2==_STMT||t2==_UNDERSCORE){
							result1.push_back(j+1);
							result2.push_back(i);//push back statement number
						}
					}
					blockEnd = stat->getBlockEnd(i);
					if(blockEnd!=-1)
						i = blockEnd;
					else{
						for(l=i+1;l<=rangeEnd;l++){
							if(stat->getParent(l)<i){
								break;
							}
						}
						i = l;
					}
				}
			}
	}
	return -1;
}

int QueryProcessor::getParT(vector<int>& result1,vector<int>& result2,int t1,int t2, int type1, int type2){
	int stmtnum, parent;
	bool boolflag = false;
	if(type2==INTARGUMENT){
		stmtnum=t2;
		while(stmtnum>1){
			parent = stat->getParent(stmtnum);
			if(parent != -1){
				if(type1 == INTARGUMENT){
					if(parent==t1){
						boolflag = true;					
						return 1;
					}
					result1.push_back(parent);
				}
				if((STATEMENT_TYPE(t1) == stat->getType(parent))  ||  t1==_STMT || t1==_UNDERSCORE){
					result1.push_back(parent);
					result2.push_back(t2);
				}
			}
			stmtnum = parent;
		}
	}
	else{
		for(unsigned int i=stat->getNoofStat()-1;i>=0;i--){
			/*isThere = false;
			for(j=0;j<result.size();j++){
			if(result[j]==i+1){
			isThere = true;
			break;
			}
			}*/
			//if(!isThere){
			stmtnum = i+1;
			if((STATEMENT_TYPE(t2)==stat->getType(stmtnum))||t2==_STMT||t2==_UNDERSCORE){
				while(stmtnum>1){
					parent = stat->getParent(stmtnum);
					if(parent!=-1){
						if((STATEMENT_TYPE(t1) == stat->getType(parent))||(t1==_STMT)||(t1==_UNDERSCORE)){
							result1.push_back(parent);
							result2.push_back(i+1);
						}
					}
					stmtnum = parent;
				}
			}
			//}
		}
	}
	if(type1==INTARGUMENT&&boolflag==false)
		return -1;
	if(result1.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getChildT(vector<int>& result1,vector<int>& result2,int t1, int t2, int type1){
	PROC_INDEX p;
	if(type1==INTARGUMENT){
		p = proc->getProcIn(t1);
		for(int j=t1+1;j<=proc->getRangeEnd(p);j++){
			if(stat->getParent(j)<t1)
				break;
			//else if(stat->getParent(j)==t1){
			if((STATEMENT_TYPE(t2) == stat->getType(j))||t2==_STMT||t2==_UNDERSCORE){
				result1.push_back(t1);
				result2.push_back(j);//push back statement
			}
			//}
		}
	}
	else{
		for(int j=0;j<stat->getNoofStat();j++)
			if((STATEMENT_TYPE(t1) == stat->getType(j+1))||t1==_STMT||t1==_UNDERSCORE){
				p = proc->getProcIn(j+1);
				for(int i=j+1; i<proc->getRangeEnd(p);i++){
					if(stat->getParent(i+1)<j+1)
						break;
					//if(stat->getParent(i+1)==j+1){
						if((STATEMENT_TYPE(t2)==stat->getType(i+1))||t2==_STMT||t2==_UNDERSCORE){
							result1.push_back(j+1);
							result2.push_back(i+1);//push back statement number
						//}
					}
				}
			}
	}
	return -1;
}

int QueryProcessor::getAffecting(vector<int>&result1, vector<int>& result2,Argument arg1, Argument arg2){
	bool boolflag = false;
	if(arg1.argumentType==INTARGUMENT){
		if(stat->getType(arg1.argument)==_ASSIGN){
			vector<int> next = *(stat->getNext(arg1.argument));
			vector<int> temp;
			bool isfound;
			if(next.size()!=0){
				for(int n=0;n<next.size();n++){
					temp.push_back(next[n]);
				}
				vector<int> varMod = *(modstat->getVarModified(arg1.argument));

				for(int i=0;i<temp.size();i++){
					if(stat->getType(temp[i])==_ASSIGN||stat->getType(temp[i])==_CALL){
						if(stat->getType(temp[i])==_ASSIGN){
							/*if(auxAffects->isAuxAffectsAvailable(stat->getAssignNumber(arg1.argument), stat->getAssignNumber(temp[i]))){
								if(auxAffects->affects(stat->getAssignNumber(arg1.argument), stat->getAssignNumber(temp[i]))){
									if(arg2.argumentType==INTARGUMENT){
										if(temp[i]==arg2.argument){
										boolflag = true;
										return 1;
										}
									}
									result2.push_back(temp[i]);
								}
							}*/

							//else 
							if(usestat->isUsed(temp[i],varMod[0])){
								//auxAffects->setAffects(stat->getAssignNumber(arg1.argument), stat->getAssignNumber(temp[i]));
								if(arg2.argumentType==INTARGUMENT){
									if(temp[i]==arg2.argument){
									boolflag = true;
									return 1;
									}
								}
								result2.push_back(temp[i]);
							}
						}
						if(modstat->isModified(temp[i],varMod[0]))
							continue;
					}

					next = *(stat->getNext(temp[i]));
					for(int n=0;n<next.size();n++){
						isfound=false;
						for(int k=0;k<temp.size();k++){
							if(temp[k]==next[n]){
								isfound = true;
								break;
							}
							/*if(temp[k]>next[n]){
							temp.insert(temp.begin()+k,next[n]);
							isfound = true;
							break;
							}*/

						}
						if(!isfound){
							temp.push_back(next[n]);
						}
					}
				}
			}
		}
	}
	else{
		int stmtnum;
		vector<int> next;
		vector<int> temp;
		vector<int> varMod;
		bool isAffectsself;
		bool boolflag = false;
		for(int k=0;k<stat->getNoofStat();k++){
			stmtnum = k+1;
			if(stat->getType(stmtnum)==_ASSIGN){
				next = *(stat->getNext(stmtnum));
				temp.clear();
				bool isfound;
				boolflag = false;
				isAffectsself = false;
				if(next.size()!=0){
					for(int n=0;n<next.size();n++){
						temp.push_back(next[n]);
					}
					 varMod = *(modstat->getVarModified(stmtnum));

					for(int i=0;i<temp.size();i++){
						if(stat->getType(temp[i])==_ASSIGN||stat->getType(temp[i])==_CALL){
							if(stat->getType(temp[i])==_ASSIGN){
								/*if(auxAffects->isAuxAffectsAvailable(stat->getAssignNumber(stmtnum), stat->getAssignNumber(temp[i]))){
									if(auxAffects->affects(stat->getAssignNumber(stmtnum), stat->getAssignNumber(temp[i]))){
										if(arg1.argument==arg2.argument&&arg1.argumentInd==arg2.argumentInd&&arg1.argument!=_UNDERSCORE){
											if(stmtnum==temp[i]){
												result1.push_back(stmtnum);
												result2.push_back(temp[i]);
												isAffectsself = true;
												break;
											}
										}
										else{
										result1.push_back(stmtnum);
										result2.push_back(temp[i]);
										if(arg2.argument==_UNDERSCORE&&arg1.argument!=_UNDERSCORE)
											break;
										}
									}
								}*/

								//else 
								if(usestat->isUsed(temp[i],varMod[0])){
									//auxAffects->setAffects(stat->getAssignNumber(stmtnum), stat->getAssignNumber(temp[i]));
									if(arg1.argument==arg2.argument&&arg1.argumentInd==arg2.argumentInd&&arg1.argument!=_UNDERSCORE){
										if(stmtnum==temp[i]){
											result1.push_back(stmtnum);
											result2.push_back(temp[i]);
											isAffectsself = true;
											break;
										}
									}
									else{
									result1.push_back(stmtnum);
									result2.push_back(temp[i]);
									if(arg2.argument==_UNDERSCORE&&arg1.argument!=_UNDERSCORE)
										break;
									}
								}
							}
							if(modstat->isModified(temp[i],varMod[0]))
								continue;
						}

						next = *(stat->getNext(temp[i]));
						for(int n=0;n<next.size();n++){
							isfound=false;
							for(int k=0;k<temp.size();k++){
								if(temp[k]==next[n]){
									isfound = true;
									break;
								}
								/*if(temp[k]>next[n]){
								temp.insert(temp.begin()+k,next[n]);
								isfound = true;
								break;
								}*/

							}
							if(!isfound){
								temp.push_back(next[n]);
							}
						}
					}
				}
			}
		}
	}
	if(arg2.argumentType==INTARGUMENT&&boolflag==false)
		return -1;
	if(result2.size()==0)
		return -1;
	return 1;
}

int QueryProcessor::getAffectedby(vector<int>& result1,vector<int>& result2,int t1 , int t2, int type2){
	vector<int> next;
	vector<int> temp1;
	vector<int> varUsed;
	if(type2==INTARGUMENT){
		if(stat->getType(t2)==_ASSIGN){
			varUsed = *(usestat->getVarUsed(t2));
			for(int j=0;j<varUsed.size();j++){
				temp1.clear();
				int x = getNextbefore(temp1,result2,_STMT,t2,type2);
				for(unsigned int i=0;i<temp1.size();i++){
					if(stat->getType(temp1[i]) == _ASSIGN){
						if(modstat->isModified(temp1[i],varUsed[j])){
							result1.push_back(temp1[i]);
							continue;
						}
					}
					else if(stat->getType(temp1[i]) == _CALL){
						if(modstat->isModified(temp1[i],varUsed[j])){
							continue;
						}
					}
					getNextbefore(temp1,result2,_STMT,temp1[i],INTARGUMENT);

				}
			}
		}
	}
	return 1;
}

int QueryProcessor::getModifies(vector<int>& result1, vector<int>& result2, int arg1arg, int arg1Type, int arg2arg, int arg2Type)
{
	STMT_LIST temp;

	int selectedType=arg1arg;

	if(arg1Type==ARGUMENT && arg2Type==VARARGUMENT)
	{
		/* Example: (p,"i") */ //Modifies
		if(arg1arg==_PROCEDURE)
			result1=*(modvar->getProcModifiedIn(arg2arg));

		/* Example: (a,"i") */ //Modifies
		else if(arg1arg==_ASSIGN)
		{
			temp=*(modvar->getStmtModifiedIn(arg2arg));

			for(unsigned int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_Assign)
					result1.push_back(temp.at(i));
			}
		}

		/* Example: (s,"i") */ //Modifies
		else if(arg1arg==_STMT)
			result1=*(modvar->getStmtModifiedIn(arg2arg));

		/* Example: (w,"i") */ //Modifies
		else if(arg1arg==_WHILE)
		{
			temp=*(modvar->getStmtModifiedIn(arg2arg));

			for(unsigned int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_While)
					result1.push_back(temp.at(i));
			}
		}

		/* Example: (if,"i") */ //Modifies
		else if(arg1arg==_IF)
		{
			temp=*(modvar->getStmtModifiedIn(arg2arg));

			for(unsigned int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_If)
					result1.push_back(temp.at(i));
			}
		}

		else if(arg1arg==_CALL)
		{
			temp=*(modvar->getStmtModifiedIn(arg2arg));

			for(unsigned int i=0;i<temp.size();i++)
			{
				if(stat->getType(temp.at(i))==STATEMENT_Call)
					result1.push_back(temp.at(i));
			}
		}


		return 2;

	}

	else if(arg1Type==ARGUMENT && arg2Type==ARGUMENT)
	{
		/* Example: Select a ... (a,v) */ //Modifies
		if(selectedType==_ASSIGN)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Assign)
				{
					temp=*(modstat->getVarModified(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();

				}
		}

		/* Example: Select s ... (s,v) */ //Modifies
		else if(selectedType==_STMT)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
			{
				temp=*(modstat->getVarModified(i));

				for(unsigned int j=0;j<temp.size();j++)
				{
					if(temp.at(j)!=-1)
					{
						if(arg2arg==_UNDERSCORE)
						{
							result1.push_back(i);
							break;
						}

						else if(arg1arg==_UNDERSCORE)
						{
							result2.push_back(temp.at(j));
							break;
						}

						else
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}

					}
				}

				temp.clear();

			}
		}

		/* Example: Select w ... (w,v) */ //Modifies
		else if(selectedType==_WHILE)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_While)
				{
					temp=*(modstat->getVarModified(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();

				}
		}

		/* Select c ... Modifies(c,v)*/
		else if(selectedType==_CALL)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Call)
				{
					temp=*(modstat->getVarModified(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();

				}
		}


		/* Example: Select if ... (if,v) */ //Modifies
		else if(selectedType==_IF)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_If)
				{
					temp=*(modstat->getVarModified(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();

				}

				return 2;
		}

		/* Example: Select p ... (p,v) */ //Modifies
		else if(selectedType==_PROCEDURE)
		{
			for(int i=0;i<proc->getSize();i++)
			{
				temp=*(modproc->getVarModified(i));

				for(unsigned int j=0;j<temp.size();j++)
				{
					if(temp.at(j)!=-1)
					{
						if(arg2arg==_UNDERSCORE)
						{
							result1.push_back(i);
							break;
						}

						else if(arg1arg==_UNDERSCORE)
						{
							result2.push_back(temp.at(j));
							break;
						}
						else
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}
				}

				temp.clear();

			}
		}

		return 2;

	}

	else if(arg1Type==INTARGUMENT && arg2Type==VARARGUMENT)
	{
		if(modstat->isModified(arg1arg, arg2arg))
			return 1;
		else return -1;

	}

	else if(arg1Type==PROCARGUMENT && arg2Type==VARARGUMENT)
	{
		if(modproc->isModified(arg1arg, arg2arg))
			return 1;
		else return -1;

	}

	return -2;

}

int QueryProcessor::getModifiedBy(vector<int>& result1, vector<int>& result2, int arg1arg, int arg1Type, int arg2arg, int arg2Type)
{
	int selectedType=arg2arg;
	STMT_LIST temp;

	/* Example: (5,v) */ //Modified By
	if(arg1Type==INTARGUMENT && arg2Type==ARGUMENT)
	{
		result2=*(modstat->getVarModified(arg1arg));

		if(arg2arg==_UNDERSCORE)
			if(result2.at(0)!=-1)
				return 1;
			else return -1;

		return 2;
	}

	/* Example: ("p",v) */ //Modified By
	else if(arg1Type==PROCARGUMENT && arg2Type==ARGUMENT)
	{
		if(arg2arg==_VARIABLE)
		{
			result2=*(modproc->getVarModified(arg1arg));
			
			if(arg2arg==_UNDERSCORE)
				if(result2.at(0)!=-1)
					return 1;
				else return -1;
		}

		return 2;
	}

	return -2;

}

int QueryProcessor::getUsess(vector<int>& result1, vector<int>& result2, int arg1arg, int arg1Type, int arg2arg, int arg2Type)
{
	int selectedType=arg1arg;
	STMT_LIST temp;

	if((arg1Type==ARGUMENT) && (arg2Type==VARARGUMENT))
	{
		/* Example: (p,"v") */ //Uses
		if(arg1arg==_PROCEDURE)
			result1=*(usevar->getProcUsedIn(arg2arg));

		/* Example: (a,"v") */ //Uses
		else if(arg1arg==_ASSIGN)
		{
			//temp=*(usevar->getStmtUsedIn(arg2arg));
			//temp=*(usestat->getStmtUsedIn(arg2arg));

			for(int i=1;i<=stat->getNoofStat();i++)
			{
				if(stat->getType(i)==STATEMENT_Assign)
					if(usestat->isUsed(i,arg2arg))
						result1.push_back(i);
				
			}
		}

		/* Example: (s,"v") */ //Uses
		else if(arg1arg==_STMT)
			//result1=*(usevar->getStmtUsedIn(arg2arg));
			result1=*(usestat->getStmtUsedIn(arg2arg));

		/* Example: (w,"v") */ //Uses
		else if(arg1arg==_WHILE)
		{
			//temp=*(usevar->getStmtUsedIn(arg2arg));
			//temp=*(usestat->getStmtUsedIn(arg2arg));

			for(int i=1;i<=stat->getNoofStat();i++)
			{
				if(stat->getType(i)==STATEMENT_While)
					if(usestat->isUsed(i,arg2arg))
						result1.push_back(i);
				
			}
		}

		/* Example: (if,"v") */ //Uses
		else if(arg1arg==_IF)
		{
			//temp=*(usevar->getStmtUsedIn(arg2arg));
			//temp=*(usestat->getStmtUsedIn(arg2arg));

			for(int i=1;i<=stat->getNoofStat();i++)
			{
				if(stat->getType(i)==STATEMENT_If)
					if(usestat->isUsed(i,arg2arg))
						result1.push_back(i);
				
			}
		}

		/* Select c ... Uses(c,"v")*/
		else if(arg1arg==_CALL)
		{
			//temp=*(usevar->getStmtUsedIn(arg2arg));
			//temp=*(usestat->getStmtUsedIn(arg2arg));

			for(int i=1;i<=stat->getNoofStat();i++)
			{
				if(stat->getType(i)==STATEMENT_Call)
					if(usestat->isUsed(i,arg2arg))
						result1.push_back(i);
				
			}
		}
		return 2;
	}

	else if((arg1Type==ARGUMENT) && (arg2Type==ARGUMENT))
	{
		/* Example: Select a ... (a,v) */ //Uses
		if(selectedType==_ASSIGN)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Assign)
				{
					temp=*(usestat->getVarUsed(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();
				}
		}

		/* Example: Select s ... (s,v) */ //Uses
		else if(selectedType==_STMT)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
			{
				temp=*(usestat->getVarUsed(i));

				for(unsigned int j=0;j<temp.size();j++)
				{
					if(temp.at(j)!=-1)
					{
						if(arg2arg==_UNDERSCORE)
						{
							result1.push_back(i);
							break;
						}

						else if(arg1arg==_UNDERSCORE)
						{
							result2.push_back(temp.at(j));
							break;
						}
						else
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}
				}

				temp.clear();
			}
		}

		/* Example: Select c ... (c,v) */ //Uses
		else if(selectedType==_CALL)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_Call)
				{
					temp=*(usestat->getVarUsed(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();
				}
		}

		/* Example: Select w ... (w,v) */ //Uses
		else if(selectedType==_WHILE)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_While)
				{
					temp=*(usestat->getVarUsed(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();
				}
		}

		/* Example: Select if ... (if,v) */ //Uses
		else if(selectedType==_IF)
		{
			for(int i=1;i<=stat->getNoofStat();i++)
				if(stat->getType(i)==STATEMENT_If)
				{
					temp=*(usestat->getVarUsed(i));

					for(unsigned int j=0;j<temp.size();j++)
					{
						if(temp.at(j)!=-1)
						{
							if(arg2arg==_UNDERSCORE)
							{
								result1.push_back(i);
								break;
							}

							else if(arg1arg==_UNDERSCORE)
							{
								result2.push_back(temp.at(j));
								break;
							}
							else
							{
								result1.push_back(i);
								result2.push_back(temp.at(j));
							}
						}
					}

					temp.clear();
				}
		}

		/* Example: Select p ... (p,v) */ //Uses
		else if(selectedType==_PROCEDURE)
		{
			for(int i=0;i<proc->getSize();i++)
			{
				temp=*(useproc->getVarUsed(i));

				for(unsigned int j=0;j<temp.size();j++)
				{
					if(temp.at(j)!=-1)
					{
						if(arg2arg==_UNDERSCORE)
						{
							result1.push_back(i);
							break;
						}

						else if(arg1arg==_UNDERSCORE)
						{
							result2.push_back(temp.at(j));
							break;
						}
						else
						{
							result1.push_back(i);
							result2.push_back(temp.at(j));
						}
					}
				}

					temp.clear();
			}


		}

		return 2;

	}

	else if(arg1Type==INTARGUMENT && arg2Type==VARARGUMENT)
	{
		if(usestat->isUsed(arg1arg, arg2arg))
			return 1;
		else return -1;

	}

	else if(arg1Type==PROCARGUMENT && arg2Type==VARARGUMENT)
	{
		if(useproc->isUsed(arg1arg, arg2arg))
			return 1;
		else return -1;

	}

	return -2;
}

int QueryProcessor::getUsedBy(vector<int>& result1, vector<int>& result2, int arg1arg, int arg1Type, int arg2arg, int arg2Type)
{
	int selectedType=arg2arg;
	STMT_LIST temp;

	/* Example: (5,v) */ //Used By
	if(arg1Type==INTARGUMENT && arg2Type==ARGUMENT)
	{
		result2=*(usestat->getVarUsed(arg1arg));

		if(arg2arg==_UNDERSCORE)
			if(result2.at(0)!=-1)
				return 1;
			else return -1;

		return 2;
	}

	else if((arg1Type==PROCARGUMENT) && (arg2Type==ARGUMENT))
	{
		/* Example: ("p",v) */ //Used By
		if(arg2arg==_VARIABLE)
		{
			result2=*(useproc->getVarUsed(arg1arg));

			if(arg2arg==_UNDERSCORE)
				if(result2.at(0)!=-1)
					return 1;
				else return -1;
		}

		return 2;
	}

	return -2;
}

//------------------Function to validate a statement or constant in a query------------------------
int QueryProcessor::validateEntity(int num, int type){
	if(type==_CONSTANT){
		int constant;
		for(int i=0;i<var->getTotalSize();i++){
			NUMERIC_EXPR_TYPE tempo;
			var->getVarType(i,tempo);
			if(tempo == NUMERIC_EXPR_TYPE_CONSTANT){
				string s = var->getVarName(i);
				constant = atoi(&s[0]);
				if(constant == num)
					return 1;
			}
		}
	}
	else if(num<=stat->getNoofStat())
		return 1;

	return -1;
}

//---------------Function to get index of variable or procedure------------------
int QueryProcessor::getEntityIndex(string e,int type){
	if(type==8) //if type is variable
		return var->getVarIndex(e);
	return proc->getProcIndex(e);//if type is procedure

}
//---------------Function to get type of entity and its index------------------
int QueryProcessor::getEntityTypeIndex(string e,int &type){
	int x = -1;
	if(type==PROCARGUMENT)
		x = proc->getProcIndex(e);
	else if(type==VARARGUMENT)
		x = var->getVarIndex(e);
	return x;
}

int QueryProcessor::getCallStmt(vector<int>& result,PROC_INDEX p){
	for(unsigned int i=1;i<=stat->getNoofStat();i++){
		if(stat->getType(i)==_CALL)
			if(stat->getConditionVar(i)==p)
				result.push_back(i);
	}
	return -1;
}

string QueryProcessor::getEntityName(int index, int type){
	if(type==_VARIABLE)
		return var->getVarName(index);
	else if(type==_PROCEDURE)
		return proc->getProcName(index);
	else if(type==_CALL)
		return proc->getProcName(stat->getConditionVar(index));
	return "ERROR";
}

int QueryProcessor::getWith(vector<int>& result1, vector<int>& result2, Argument arg1, Argument arg2){
	if(arg1.argument==_PROCEDURE){
			if(arg2.argument==_PROCEDURE){
				for(int i=0;i<proc->getSize();i++){
					result2.push_back(i);
					result1.push_back(i);
				}
			}
			else if(arg2.argument==_VARIABLE){
				for(int i=0;i<var->getTotalSize();i++){
					NUMERIC_EXPR_TYPE tempo;
					var->getVarType(i,tempo);
					if(tempo == NUMERIC_EXPR_TYPE_VARIABLE){
						for(int j=0;j<proc->getSize();j++)
							if((var->getVarName(i).compare(proc->getProcName(j))==0)){
								result1.push_back(j);
								result2.push_back(i);
								break;
							}
					}
				}
			}
			else if(arg2.argument==_CALL&&arg2.withAttribute==_PROCNAME){
				for(int i=1;i<=stat->getNoofStat();i++){
					if(stat->getType(i)==_CALL){
						int procedure = stat->getConditionVar(i);
						if(procedure<proc->getSize()){
							result1.push_back(procedure);
							result2.push_back(i);
						}
					}
				}
			}
	}
	else if(arg1.argument==_VARIABLE){
		if(arg2.argument==_VARIABLE){
			for(int i=0;i<var->getTotalSize();i++){
				NUMERIC_EXPR_TYPE tempo;
				var->getVarType(i,tempo);
				if(tempo == NUMERIC_EXPR_TYPE_VARIABLE){
					result2.push_back(i);
					result1.push_back(i);
				}
			}
		}
		else if(arg2.argument==_PROCEDURE){
			for(int i=0;i<var->getTotalSize();i++){
				NUMERIC_EXPR_TYPE tempo;
				var->getVarType(i,tempo);
				if(tempo == NUMERIC_EXPR_TYPE_VARIABLE){
					for(int j=0;j<proc->getSize();j++)
						if(var->getVarName(i).compare(proc->getProcName(j))==0){
							result1.push_back(i);
							result2.push_back(j);
							break;
						}
				}
			}
		}
		else if(arg2.argument==_CALL&&arg2.withAttribute==_PROCNAME){
			for(int i=1;i<=stat->getNoofStat();i++){
				if(stat->getType(i)==_CALL){
					int procedure = stat->getConditionVar(i);
					if(procedure<proc->getSize()){
						for(int j=0;j<var->getTotalSize();j++){
							if(var->getVarName(j).compare(proc->getProcName(procedure))==0){
								result1.push_back(j);
								result2.push_back(i);		
							}
						}
					}
				}
			}
		}
	}
	//check what to do for call.procname = call .procname
	//As of now returns statement numbers of call statements
	else if(arg1.argument==_CALL&&arg1.withAttribute==_PROCNAME){
		if(arg2.argument==_CALL&&arg2.withAttribute==_PROCNAME){
			for(int i=1;i<stat->getNoofStat();i++){
				if(stat->getType(i)==_CALL){
					//int procedure = stat->getConditionVar(i);
					result1.push_back(i);
					result2.push_back(i);
				}
			}
		}
		else if(arg2.argument==_PROCEDURE){
			for(int i=1;i<=stat->getNoofStat();i++){
				if(stat->getType(i)==_CALL){
					int procedure = stat->getConditionVar(i);
					if(procedure<proc->getSize()){
						result1.push_back(i);
						result2.push_back(procedure);
					}
				}
			}
		}
		else if(arg2.argument==_VARIABLE){
			for(int i=1;i<=stat->getNoofStat();i++){
				if(stat->getType(i)==_CALL){
					int procedure = stat->getConditionVar(i);
					if(procedure<proc->getSize()){
						for(int j=0;j<var->getTotalSize();j++){
							if(var->getVarName(j).compare(proc->getProcName(procedure))==0){
								result1.push_back(j);
								result2.push_back(i);		
							}
						}
					}
				}
			}
		}
	}
	else if(arg2.argument==_CONSTANT){
		int constant;
		NUMERIC_EXPR_TYPE tempo;
		if(arg1.argument==_CONSTANT){
			for(int i=0;i<var->getTotalSize();i++){
				var->getVarType(i,tempo);
				if(tempo == NUMERIC_EXPR_TYPE_CONSTANT){
					string s = var->getVarName(i);
					constant = atoi(&s[0]); 
					result1.push_back(constant);
					result2.push_back(constant);
				}
			}
		}
		else{
			for(int i=0;i<var->getTotalSize();i++){
				var->getVarType(i,tempo);
				if(tempo == NUMERIC_EXPR_TYPE_CONSTANT){
					string s = var->getVarName(i);
					constant = atoi(&s[0]);
					if(constant<=stat->getNoofStat()){
						if(stat->getType(constant) == arg1.argument||arg1.argument==_STMT){
							result1.push_back(constant);
							result2.push_back(constant);
						}
					}
				}
			}
		}
	}
	else if(arg1.argument==arg2.argument){
		for(int i=1;i<=stat->getNoofStat();i++){
			if(stat->getType(i)==arg1.argument||arg1.argument==_STMT){
				result1.push_back(i);
				result2.push_back(i);
			}
		}
	}
	else if(arg1.argument==_STMT){
		for(int i=1;i<=stat->getNoofStat();i++){
			if(stat->getType(i)==arg2.argument){
				result1.push_back(i);
				result2.push_back(i);
			}
		}
	}
	else if(arg2.argument==_STMT){
		for(int i=1;i<=stat->getNoofStat();i++){
			if(stat->getType(i)==arg1.argument){
				result1.push_back(i);
				result2.push_back(i);
			}
		}
	}
	if(result1.size()==0||result2.size()==0)
		return -1;
	return 1;
	}